package com.tarena.lbs.coupon.dao.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.attach.pojo.dto.AttachQrDTO;
import com.tarena.lbs.attach.pojo.param.AttachQRParam;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.business.api.pojo.StoreDto;
import com.tarena.lbs.coupon.dao.mapper.CouponCodeMapper;
import com.tarena.lbs.coupon.dao.mapper.CouponMapper;
import com.tarena.lbs.coupon.dao.mapper.UserCouponsMapper;
import com.tarena.lbs.coupon.dao.repository.CouponRepository;
import com.tarena.lbs.coupon.pojo.dto.CouponDto;
import com.tarena.lbs.coupon.pojo.po.CouponCodePO;
import com.tarena.lbs.coupon.pojo.po.CouponPO;
import com.tarena.lbs.coupon.pojo.po.UserCouponsPO;
import com.tarena.lbs.coupon.pojo.query.UserCouponCodeQuery;
import com.tarena.lbs.coupon.pojo.vo.CouponVO;
import com.tarena.lbs.coupon.pojo.vo.UserCouponsVO;
import com.tarena.lbs.user.api.UserApi;
import com.tarena.lbs.business.api.BusinessApi;
import com.tarena.lbs.user.api.pojo.dto.AdminDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Repository("couponRepository")
@Slf4j
public class CouponRepositoryImpl implements CouponRepository {

    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private CouponCodeMapper couponCodeMapper;

    // 注入RedisTemplate
//    @Autowired
//    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserCouponsMapper userCouponsMapper;
    @DubboReference
    private UserApi userApi;

    @DubboReference
    private BusinessApi businessApi;

    @Autowired
    private RedisTemplate redisTemplate;
    @DubboReference
    private AttachApi attachApi;
    @Override
    public UserCouponsVO receiveDetail(UserCouponCodeQuery query) {
        // 构造查询条件，根据用户ID和优惠券码查询用户优惠券信息
        QueryWrapper<UserCouponsPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",query.getUserId());
        queryWrapper.eq("coupon_code",query.getCouponCode());
        // 查询用户优惠券信息
        UserCouponsPO userCouponsPO = userCouponsMapper.selectOne(queryWrapper);
        // 创建VO对象并拷贝基础属性
        UserCouponsVO userCouponsVO = new UserCouponsVO();
        BeanUtils.copyProperties(userCouponsPO,userCouponsVO);

        // 根据优惠券ID查询优惠券详细信息
        QueryWrapper<CouponPO> couponQueryWrapper = new QueryWrapper<>();
        couponQueryWrapper.eq("id",userCouponsPO.getCouponId());
        CouponPO couponPO = couponMapper.selectOne(couponQueryWrapper);
        // 设置优惠券名称
        userCouponsVO.setCouponName(couponPO.getCouponName());
        // 调用远程服务获取商户信息并设置店铺名称
        StoreDto storeDto = businessApi.getStoreById(userCouponsPO.getShopId());
        userCouponsVO.setShopName(storeDto.getStoreName());
        // 从Redis中获取二维码URL，如果不存在则生成新的二维码
        String url = (String) redisTemplate.opsForValue().get(query.getCouponCode());
        if (url == null){
            // 创建二维码参数并调用远程服务生成二维码
            AttachQRParam qrParam = new AttachQRParam(query.getCouponCode(), 500, couponPO.getBusinessId());
            AttachQrDTO qrDTO = attachApi.generateQrCode(qrParam);
            url =  qrDTO.getUrl();
            // 将生成的二维码URL缓存到Redis中
            redisTemplate.opsForValue().set(query.getCouponCode(),url);
        }
        // 设置二维码URL
        userCouponsVO.setCouponUrl(url);
        return userCouponsVO;
    }

    @Override
    public PageResult<CouponVO> pageList(Integer userId) {
        //设置初始页码为1，每页显示10条记录
        Page<CouponPO> page = new Page<>(1, 10);
        QueryWrapper<CouponPO> queryWrapper = new QueryWrapper<>();
        //从 AdminDto 对象中获取 businessId
        AdminDto adminDto = userApi.getAdminById(userId);
        Integer businessId = adminDto.getBusinessId();
        log.info("businessId:" + businessId);
        queryWrapper.eq("business_id", businessId);
        couponMapper.selectPage(page, queryWrapper);
        List<CouponPO> couponPOS = page.getRecords();
        List<CouponVO> couponVOS = new ArrayList<>();
        for (CouponPO couponPO : couponPOS) {
            QueryWrapper<CouponCodePO> codeQueryWrapper = new QueryWrapper<>();
            codeQueryWrapper.eq("coupon_id", couponPO.getId());
            codeQueryWrapper.eq("business_id", businessId);
            CouponCodePO couponCodePO = couponCodeMapper.selectOne(codeQueryWrapper);
            CouponVO couponVO = new CouponVO();
            BeanUtils.copyProperties(couponPO, couponVO);
            // 添加空值检查，防止 NullPointerException
            if (couponCodePO != null) {
                couponVO.setCouponCode(couponCodePO.getCouponCode());
            } else {
                // 当查询不到优惠券编码时，设置默认值或空字符串
                couponVO.setCouponCode("");
            }
            couponVOS.add(couponVO);
        }
        PageResult<CouponVO> pageResult = new PageResult<>();
        pageResult.setObjects(couponVOS);
        pageResult.setTotal(page.getTotal());
        pageResult.setPageNo((int) page.getCurrent());
        pageResult.setPageSize((int) page.getSize());
        return pageResult;
    }

    @Override
    public int generateCoupon(CouponPO po) {
        // 到这才反应过来可以用实体类entity，那就转换一下吧。
        int result;
        try {
            result = couponMapper.insert(po);
            if (result != 1) {
                log.error("优惠券插入失败，couponId={}", po.getId());
                throw new RuntimeException("优惠券插入失败");
            }
        } catch (Exception e) {
            log.error("优惠券插入异常，couponId={}", po.getId(), e);
            throw new RuntimeException("优惠券插入异常: " + e.getMessage(), e);
        }
        return result;
    }

    @Override
    public CouponVO detail(Integer id) {
        // 根据ID查询优惠券信息
//        CouponPO couponPO = couponMapper.selectById(null);
        CouponPO couponPO = couponMapper.selectById(id);
        // 创建VO对象并复制PO属性
        CouponVO couponVO = new CouponVO();
        BeanUtils.copyProperties(couponPO, couponVO);
        // 查询关联的优惠码信息
        QueryWrapper<CouponCodePO> codeQueryWrapper = new QueryWrapper<>();
        codeQueryWrapper.eq("coupon_id", couponPO.getId());
        List<CouponCodePO> couponCodePOs = couponCodeMapper.selectList(codeQueryWrapper);
        // 设置优惠卷码到VO对象
        // 设置优惠卷码到VO对象（添加空值检查）
        if (couponCodePOs.size() >0) {
            log.info("查询到优惠券编码，随机展示一个编码");
            couponVO.setCouponCode(couponCodePOs.get(0).getCouponCode());
        } else {
            log.warn("该优惠券还未分配给用户，暂无编码，id={}", couponPO.getId());
            couponVO.setCouponCode("");
        }
        return couponVO;
    }

    @Deprecated
    public CouponPO findByIdByRedis(Integer id) {
//        // 先从Redis缓存中获取
//        String key = "coupon:" + id;
//        CouponPO couponPO = (CouponPO) redisTemplate.opsForValue().get(key);
//
//        if (couponPO != null) {
//            log.info("从Redis缓存中获取优惠券信息，id={}", id);
//            return couponPO;
//        }
//
//        // 如果缓存中没有，则从数据库查询
//        couponPO = couponMapper.selectById(id);
//        if (couponPO == null) {
//            log.error("未查询到优惠券表的对应记录，id={}", id);
//            throw new RuntimeException("优惠券不存在");
//        } else {
//            log.info("从数据库中查询到优惠券，id={}", id);
//            // 将查询结果放入Redis缓存，设置过期时间为30分钟
//            redisTemplate.opsForValue().set(key, couponPO, 30, TimeUnit.MINUTES);
//        }
//        return couponPO;
        throw new UnsupportedOperationException("暂不支持该功能");
    }

    @Override
    public CouponPO findById(Integer id) {
        // 直接从数据库查询
        CouponPO couponPO = couponMapper.selectById(id);
        if (couponPO == null) {
            log.error("未查询到优惠券表的对应记录，id={}", id);
        } else {
            log.info("查询到优惠券，id={}", id);
            log.info("从数据库中查询到优惠券，id={}", id);
        }
        return couponPO;
    }

    @Override
    public int updateCoupon(CouponPO couponPO) {
        int result = couponMapper.updateByIdByXml(couponPO);
        if (result != 1) {
            log.error("更新优惠券表出现异常，影响行数={}，id={}", result, couponPO.getId());
            throw new RuntimeException("优惠券更新失败");
        }
        log.info("更新优惠券表成功，id={}", couponPO.getId());
        // 更新成功后，删除Redis中的缓存
        String key = "coupon:" + couponPO.getId();
//        redisTemplate.delete(key);
        return result;
    }

    /**
     * 优惠券列表查询
     *
     * @param couponPO 查询条件
     * @param pageNum  页码
     * @param pageSize 每页数量
     * @return 优惠券列表
     */
    @Override
    public PageResult<CouponPO> pageList(CouponPO couponPO, int pageNum, int pageSize) {
        try {
            // 设置分页参数
            Page<CouponPO> page = new Page<>(pageNum, pageSize);
            QueryWrapper<CouponPO> queryWrapper = new QueryWrapper<>();

            // 根据couponPO的属性构建查询条件

            // ID精确查询
            if (couponPO.getId() != null) {
                queryWrapper.eq("id", couponPO.getId());
            }

            // 商家ID
            if (couponPO.getBusinessId() != null) {
                queryWrapper.eq("business_id", couponPO.getBusinessId());
            }

            // 优惠券名称（模糊查询）
            if (couponPO.getCouponName() != null && !couponPO.getCouponName().isEmpty()) {
                queryWrapper.like("coupon_name", couponPO.getCouponName());
            }

            // 优惠券类型
            if (couponPO.getCouponType() != null) {
                queryWrapper.eq("coupon_type", couponPO.getCouponType());
            }

            // 优惠券状态
            if (couponPO.getStatus() != null) {
                queryWrapper.eq("status", couponPO.getStatus());
            }

            // 优惠券描述（注意：实体类中字段名为describes）
            if (couponPO.getDescribes() != null && !couponPO.getDescribes().isEmpty()) {
                queryWrapper.like("describes", couponPO.getDescribes());
            }

            // 折扣值范围查询
            if (couponPO.getDiscountValue() != null) {
                queryWrapper.eq("discount_value", couponPO.getDiscountValue());
            }

            // 最大折扣金额
            if (couponPO.getMaxDiscountAmount() != null) {
                queryWrapper.eq("max_discount_amount", couponPO.getMaxDiscountAmount());
            }

            // 订单金额要求
            if (couponPO.getOrderAmount() != null) {
                queryWrapper.eq("order_amount", couponPO.getOrderAmount());
            }

            // 使用次数限制
            if (couponPO.getUsageLimit() != null) {
                queryWrapper.eq("usage_limit", couponPO.getUsageLimit());
            }

            // 最大使用次数限制
            if (couponPO.getMaxUsageLimit() != null) {
                queryWrapper.eq("max_usage_limit", couponPO.getMaxUsageLimit());
            }

            // 有效期范围查询
            if (couponPO.getStartDate() != null) {
                queryWrapper.ge("start_date", couponPO.getStartDate());
            }
            if (couponPO.getEndDate() != null) {
                queryWrapper.le("end_date", couponPO.getEndDate());
            }

            // 创建时间范围
            if (couponPO.getCreateAt() != null) {
                queryWrapper.ge("create_at", couponPO.getCreateAt());
            }
            if (couponPO.getUpdateAt() != null) {
                queryWrapper.le("update_at", couponPO.getUpdateAt());
            }

            // 使用次数
            if (couponPO.getUsageNum() != null) {
                queryWrapper.eq("usage_num", couponPO.getUsageNum());
            }

            // 启用状态
            if (couponPO.getEnableStatus() != null) {
                queryWrapper.eq("enable_status", couponPO.getEnableStatus());
            }

            // 排斥类型
            if (couponPO.getExclusionType() != null) {
                queryWrapper.eq("exclusion_type", couponPO.getExclusionType());
            }

            // 适用范围
            if (couponPO.getApplicable() != null && !couponPO.getApplicable().isEmpty()) {
                queryWrapper.eq("applicable", couponPO.getApplicable());
            }

            // 默认按创建时间倒序排列
            queryWrapper.orderByDesc("create_at");

            couponMapper.selectPage(page, queryWrapper);

            // 构建完整的PageResult，包含分页信息
            PageResult<CouponPO> pageResult = new PageResult<>();
            pageResult.setObjects(page.getRecords());
            pageResult.setTotal(page.getTotal());
            pageResult.setPageNo((int) page.getCurrent());
            pageResult.setPageSize((int) page.getSize());

            return pageResult;
        } catch (Exception e) {
            // 记录异常日志
            log.error("分页查询优惠券失败", e);
            throw new RuntimeException("分页查询优惠券失败", e);
        }
    }



}